在過去的實作中,帶各位練習好幾次的 events
但在 widget
還有一個特別的屬性 custom_events
而這兩者的差別是
events
: 基本上為一般常見的 Dom eventcustom_events
: 不是 Dom event,但在多個地方可以套用,觸發的方式是用 trigger_up()
來呼叫定義的 key
各位若還有印象,曾經有在第 21 天有出現過關鍵字
但要注意的是,並不是每個 custom_events
都可以在所有組件使用
除非呼叫的是 service
(也是第 21 天的底層有出現)
簡單帶各位觀察 abstract_web_client
的 custom_events
// addons/web/static/src/js/chrome/abstract_web_client.js
var AbstractWebClient = Widget.extend(KeyboardNavigationMixin, {
// ...
custom_events: {
call_service: '_onCallService',
clear_uncommitted_changes: function (e) {
this.clear_uncommitted_changes().then(e.data.callback);
},
toggle_fullscreen: function (event) {
this.toggle_fullscreen(event.data.fullscreen);
},
current_action_updated: function (ev) {
this.current_action_updated(ev.data.action, ev.data.controller);
},
// GENERIC SERVICES
// the next events are dedicated to generic services required by
// downstream widgets. Mainly side effects, such as rpcs, notifications
// or cache.
warning: '_onDisplayWarning',
load_action: '_onLoadAction',
load_views: function (event) {
var params = {
model: event.data.modelName,
context: event.data.context,
views_descr: event.data.views,
};
return data_manager
.load_views(params, event.data.options || {})
.then(event.data.on_success);
},
load_filters: function (event) {
return data_manager
.load_filters(event.data)
.then(event.data.on_success);
},
create_filter: '_onCreateFilter',
delete_filter: '_onDeleteFilter',
push_state: '_onPushState',
show_effect: '_onShowEffect',
// session
get_session: function (event) {
if (event.data.callback) {
event.data.callback(session);
}
},
do_action: function (event) {
const actionProm = this.do_action(event.data.action, event.data.options || {});
this.menu_dp.add(actionProm).then(function (result) {
if (event.data.on_success) {
event.data.on_success(result);
}
}).guardedCatch(function (result) {
if (event.data.on_fail) {
event.data.on_fail(result);
}
});
},
getScrollPosition: '_onGetScrollPosition',
scrollTo: '_onScrollTo',
set_title_part: '_onSetTitlePart',
webclient_started: '_onWebClientStarted',
},
// ...
},
有沒有發現在這裡有定義了很多 custom event
包含之前提到的 call_service
所以各位在繼承任何的 widget 時,若不確定有什麼可以使用
可以斷點停在任何一個生命週期的階段,在 console 執行下方程式
this.custom_events // 自訂事件
this.events // Dom 事件
額外提醒,在繼承時,若有定義事件,若不是要覆蓋,而是要擴展的話,要這樣寫才會正常
events: {
...(AbstractAction.prototype.events || {}), // <-- This line
'change .finished': '_toggleFinish',
'click i.fa-times': '_removeItem',
'click .btn-new-todo': '_newItem',
'click i.fa-check': '_saveItem',
'click .todo-name': '_editItem',
'click .jump-to-so': '_jump2SO',
},
custom_events: {
...(AbstractAction.prototype.custom_events || {}), // <-- This line
'ironman_custom_event': '_ironman',
},